﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using PersonalAlbum.Caching;
using MyAlbum.Model;
using System.Configuration;
using System.IO;
using System.Xml.Linq;
using MyAlbum.Services;
using System.Security.Permissions;
using System.Collections.Specialized;
using MyAlbum.Logging;
using System.Collections.ObjectModel;

namespace PersonalAlbum
{
    public class PersonalAlbumModel
    {
        private ILanguageService _lang;
        private IUser _user;
        private IConfiguration _config;
        
        public PersonalAlbumModel(IUser user, ILanguageService lang, IConfiguration config)
        {
            this._user = user;
            this._lang = lang;
            this._config = config;
        }

        /// <summary>
        /// Gets the language traslation according to the current user's request
        /// </summary>
        /// <param name="label"></param>
        /// <returns></returns>
        public string Localize(string label)
        {
            return _lang.GetText(label);
        }
        public string TextDirection
        {
            get
            {
                return _lang.TextDirection;
            }
        }
        public ILanguageService Languages
        {
            get
            {
                return _lang;
            }
        }
        public IConfiguration Configuration
        {
            get
            {
                return _config;
            }
        }
        public IUser User
        {
            get
            {
                return _user;
            }
        }
        public IEnumerable<PostEntry> Posts { get; set; }
        public PostEntry Post { get; set; }
        public IEnumerable<Section> Sections { get; set; }
        public IEnumerable<Album> Albums { get; set; }
        public string ParentSection { get; set; }
        public IEnumerable<Entry> RandomEntries { get; set; }
        public Entry LatestEntry { get; set; }
        public Entry CurrentEntry { get; set; }
        public Album CurrentAlbum { get; set; }
        public IEnumerable<Tag> TagsCloud { get; set; }
        public List<MonthSummary> MonthsView { get; set; }
        public string ParentAlbum { get; set; }
        public IEnumerable<Entry> Entries { get; set; }
        public int CurrentPage { get; set; }
        public int PagesCount { get; set; }
        public Section CurrentSection { get; set; }
        public string ErrorMessage { get; set; }
        public string ReturnUrl { get; set; }
        public List<IUser> Users { get; set; }
        public IEnumerable<Support> SupportRequests { get; set; }
        public ReadOnlyCollection<Extension> Extensions { get; set; }
        public IEnumerable<Entrance> Entrances { get; set; }
        public IEnumerable<Reply> Replies { get; set; }
        public Statistics Statistics { get; set; }
    }



    //we can't use enums as the names should be readable in the xml file,
    //but this is still better than magic strings

    public class ConfigManager
    {
        private static string _appDataPhysicalPath;
        private static IConfiguration _configuration;
        private const string ConfigFilePath = "~/App_Data/SiteConfig.xml";
        public const string ImagesPath = "~/Content/Images";
        public static bool Initalize(out string result)
        {
            ConfigManager.AppDataPhysicalPath = HttpContext.Current.Server.MapPath("~/App_Data");

            try
            {
                if (!CheckIfConfigFileExists())
                {
                    result = "Config file is missing : " + ConfigFilePath;
                    return false;
                }
            }
            catch (Exception e1)
            {
                result = "Error accessing config file on " + ConfigFilePath + ". Error message:" + e1.Message;
                return false;
            }
            try
            {
                //trigger the load config values
                _configuration = ObjectFactory.GetInstance<IConfiguration>();
            }
            catch (Exception e1)
            {
                result = "Error loading config values. Error message:" + e1.Message;
                return false;
            }
            try
            {
                CheckWritePermissionsOnContentPath();
            }
            catch (Exception e1)
            {
                result = "Error writing to path \"" + ImagesPath + "\". Error message:" + e1.Message;
                return false;
            }

            try
            {
                CheckWritePermissionsOnDataPath();
            }
            catch (Exception e1)
            {
                result = "Error writing to path \"App_Data\". Error message:" + e1.Message;
                return false;
            }
            result = null;
            return true;
        }
        public static bool UseCache
        {
            get
            {
                return false;
            }
        }
        public static string SiteTitle
        {
            get
            {
                return _configuration.SiteTitle;
            }
        }

        public static bool UseCaptcha
        {
            get
            {
                return _configuration.UseCaptcha;
            }
        }
        public static int ThumbDefaultWidth
        {
            get
            {
                return _configuration.ThumbDefaultWidth;
            }
        }
        public static int ThumbDefaultHeight
        {
            get
            {
                return _configuration.ThumbDefaultHeight;
            }
        }
        
        private static void CheckWritePermissionsOnDataPath()
        {
            FileIOPermission io = new FileIOPermission(FileIOPermissionAccess.Append | FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, HttpContext.Current.Server.MapPath("~/App_Data"));
            io.Demand();

        }

        private static void CheckWritePermissionsOnContentPath()
        {
            FileIOPermission io = new FileIOPermission(FileIOPermissionAccess.AllAccess, HttpContext.Current.Server.MapPath("~/Content"));
            io.Demand();
            if (!Directory.Exists(HttpContext.Current.Server.MapPath(ImagesPath)))
            {
                Directory.CreateDirectory(HttpContext.Current.Server.MapPath(ImagesPath));
            }
            io = new FileIOPermission(FileIOPermissionAccess.AllAccess, HttpContext.Current.Server.MapPath(ImagesPath));
            io.Demand();
        }

        private static bool CheckIfConfigFileExists()
        {
            return File.Exists(HttpContext.Current.Server.MapPath(ConfigFilePath));
        }

      

       

        /// <summary>
        /// Gets or sets the physical path to the app_data folder. 
        /// We this value set on the aplication start as the HttpContext is 
        /// not available on the controllers constructor and we need it for
        ///  the xml data source
        /// </summary>
        public static string AppDataPhysicalPath
        {
            get
            {
                return _appDataPhysicalPath;
            }
            set
            {
                _appDataPhysicalPath = value;
            }
        }

        public static string ThemePath
        {
            get
            {
                return _configuration.ThemePath;
            }
        }

        public static string AdminEmail
        {
            get
            {
                return _configuration.AdminEmail;
            }
        }

        public static string SiteUrl
        {
            get
            {
                return HttpContext.Current.Request.Url.Scheme + "://"
                + HttpContext.Current.Request.Url.Authority;
            }
        }



    }
}
